TOOL.Category    = "Conna's Tools"
TOOL.Name        = "#Timer Tool"
TOOL.Command     = nil
TOOL.ConfigName  = ""

// ConVars

TOOL.ClientConVar["Interval"] = ""
TOOL.ClientConVar["Description"] = ""
TOOL.ClientConVar["Key"] = "5"

// Register

cleanup.Register("timers")

// Console

CreateConVar("sbox_maxtimers", 10, FCVAR_NOTIFY)

// Client

if (CLIENT) then
	// Tool
	
	language.Add("Tool_timer_name", "Timer Tool")
	language.Add("Tool_timer_desc", "Timer which presses a key at a set interval")
	language.Add("Tool_timer_0", "Left click to spawn a Timer")
	
	// Other
	
	language.Add("Undone_timer", "Undone Timer")
	language.Add("SBoxLimit_timers", "You've hit the Timers limit!")
	language.Add("Cleanup_timers", "Timers")
	language.Add("Cleaned_timers", "Cleaned up all Timers")
end

// Message

function TOOL:Message(Text)
	if SERVER then
		self:GetOwner():SendLua("GAMEMODE:AddNotify('"..Text.."', NOTIFY_GENERIC, 10)")
		self:GetOwner():SendLua("surface.PlaySound('ambient/water/drip"..math.random(1, 4)..".wav')")
	end
end

// Left click

function TOOL:LeftClick(Trace)
	if(CLIENT) then
		return true
	end
	
	// Locals
	
	local Player = self:GetOwner()

	local Key = self:GetClientNumber("Key")
	local Interval = self:GetClientNumber("Interval")
	local Description = self:GetClientInfo("Description")
	
	// Keep it nice and whole
	
	Interval = math.floor(Interval)
	Interval = math.max(Interval, 0)
	
	if (Trace.Entity and Trace.Entity:IsValid() and Trace.Entity:GetClass() == "gmod_timer") then
		local Entity = Trace.Entity
		
		// Merge
		
		local Table = {
			Key = Key,
			Interval = Interval,
			Description = Description
		}
		
		table.Merge(Entity:GetTable(), Table)
		
		// Other
		
		Entity:GetTable():Setup()
		Entity:GetTable():SetEntityKey(Key)
		Entity:GetTable():SetEntityLabel(Description)
		
		self:Message("Properties changed for Timer!")
		
		return true
	end
	
	local Ang = Trace.HitNormal:Angle()
	
	Ang.pitch = Ang.pitch + 90

	local Timer = CreateTimer(Player, Ang, Trace.HitPos, Interval, Key, Description)
	
	if not (Timer) then return false end
	
	local Minimum = Timer:OBBMins()
	
	Timer:SetPos(Trace.HitPos - Trace.HitNormal * Minimum.z)
	
	undo.Create("timer")
	
	if (Trace.Entity and not Trace.Entity:IsWorld()) then
		local Weld = constraint.Weld(Timer, Trace.Entity, 0, Trace.PhysicsBone, 0, true, true)
		
		undo.AddEntity(Weld)
		
		Player:AddCleanup("timers", Weld)
		
		Timer:GetPhysicsObject():EnableCollisions(false)
	end
	
	undo.AddEntity(Timer)
	undo.SetPlayer(Player)
	
	undo.Finish()
	
	Player:AddCount("timers", Timer)
	
	Player:AddCleanup("timers", Timer)
	
	self:Message("Timer has been created!")
	
	return true, Timer
end

// Make it

if (SERVER) then
	function CreateTimer(Player, Ang, Pos, Interval, Key, Description, Nocollide, Vel, Avel, Frozen)
		if (!Player:CheckLimit("timers")) then return false end
		
		local Timer = ents.Create("gmod_timer")
		
		Timer:SetModel("models/props_c17/clock01.mdl")
		Timer:SetAngles(Ang)
		Timer:SetPos(Pos)
		Timer:Spawn()
		
		// Merge
		
		local Table = {
			Key = Key,
			Interval = Interval,
			Description = Description
		}
		
		table.Merge(Timer:GetTable(), Table)
		
		// Set the entities owner
		
		Timer:GetTable():SetPlayer(Player)
		
		// Other
		
		Timer:GetTable():Setup()
		Timer:GetTable():SetEntityKey(Key)
		Timer:GetTable():SetEntityLabel(Description)
		
		if Frozen then Timer:GetPhysicsObject():EnableMotion(false) end

		if Nocollide then Timer:GetPhysicsObject():EnableCollisions(false) end
		
		return Timer
	end
	
	duplicator.RegisterEntityClass("gmod_timer", CreateTimer, "Ang", "Pos", "Interval", "Key", "Description", "Nocollide", "Vel", "Avel", "Frozen")
end

// Control panel

function TOOL.BuildCPanel(Panel)
	Panel:AddControl("Header", {Text = "#Tool_timer_name", Description = "#Tool_timer_desc"})
	
	Panel:AddControl("Slider", {Label = "Interval", Type = "Integer", Min = 0, Max = 60, Command = "timer_Interval"})
	
	Panel:AddControl("Numpad", {Label = "Key", Command = "timer_Key", ButtonSize = 22})

	Panel:AddControl("TextBox", {Label = "Description", MaxLength = "100", Command = "timer_Description"})
end

// Ghost

function TOOL:UpdateGhostTimer(Entity, Player)
	if (!Entity) then return end
	
	if (!Entity:IsValid()) then return end

	local TR = utilx.GetPlayerTrace(Player, Player:GetCursorAimVector())
	
	local Trace = util.TraceLine(TR)
	
	if (!Trace.Hit) then return end
	
	if (Trace.Entity && Trace.Entity:GetClass() == "gmod_timer" || Trace.Entity:IsPlayer()) then
		Entity:SetNoDraw(true)
		
		return
	end
	
	local Ang = Trace.HitNormal:Angle()
	
	Ang.pitch = Ang.pitch + 90
	
	local Minimum = Entity:OBBMins()
	
	Entity:SetPos(Trace.HitPos - Trace.HitNormal * Minimum.z)
	
	Entity:SetAngles(Ang)
	
	Entity:SetNoDraw(false)
end

// Think

function TOOL:Think()
	if (self:GetOwner() and self:GetOwner():IsPlayer()) then
		if (!self.GhostEntity || !self.GhostEntity:IsValid() || self.GhostEntity:GetModel() != "models/props_c17/clock01.mdl") then
			self:MakeGhostEntity("models/props_c17/clock01.mdl", Vector(0, 0, 0), Angle(0, 0, 0) )
		end
		
		self:UpdateGhostTimer(self.GhostEntity, self:GetOwner())
	end
end